package com.wxzhou.wangzhuan.repository;

import com.wxzhou.wangzhuan.constants.LoginEvent;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.sqlclient.Pool;
import io.vertx.mutiny.sqlclient.Tuple;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.jboss.logging.Logger;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 登录持久层
 */
@ApplicationScoped
public class LoginEventRespository {

    private static final Logger LOG = Logger.getLogger(LoginEventRespository.class);
    @Inject
    Pool client;

    /**
     * 批量插入
     * @param loginEvents
     * @return
     */
    public Uni<Integer> batchInsertComments(List<LoginEvent> loginEvents) {
        if (loginEvents == null || loginEvents.isEmpty()) {
            return Uni.createFrom().item(0);
        }

        // 安全检查：确保批量大小在合理范围内
        final int MAX_BATCH_SIZE = 2000; // 最大批量大小
        if (loginEvents.size() > MAX_BATCH_SIZE) {
            LOG.warnf("wz_Login_event", "批量登录日志数量过大，建议分批处理",
                    "requestedSize=" + loginEvents.size() + ", maxBatchSize=" + MAX_BATCH_SIZE);
            // 这里可以选择抛出异常或者继续处理，为了兼容性选择继续处理
        }

        // 计算SQL参数数量：每条7个字段
        final int FIELDS_PER_COMMENT = 7;
        final int totalParams = loginEvents.size() * FIELDS_PER_COMMENT;

        // 安全检查：确保参数数量在合理范围内
        final int MAX_PARAMS = 50000; // 最大参数数量限制
        if (totalParams > MAX_PARAMS) {
            LOG.errorf("wz_Login_event", "批量登录日志参数数量过多，可能导致性能问题",
                    "totalParams=" + totalParams + ", maxParams=" + MAX_PARAMS +
                            ", commentCount=" + loginEvents.size());
            return Uni.createFrom().failure(new IllegalArgumentException(
                    "批量登录日志参数数量过多: " + totalParams + " > " + MAX_PARAMS));
        }


        List<String> insertColumns = Arrays.asList("created_at", "deviceid", "user_id", "ip_address", "login_type", "success", "failure_reason");

        // 列名拼接
        String columns = String.join(", ", insertColumns);

        // 动态生成占位符（$1, $2, $3...）
        List<String> placeholderList = new ArrayList<>();
        //批量构造插入语句
        int tempindex = 0;
        List tuples = new ArrayList();
        for (int i = 0; i < loginEvents.size(); i++) {
            LoginEvent loginEvent = loginEvents.get(i);
            List<String> tempPlaceholderList = new ArrayList<>();
            for (int j = 0; j < insertColumns.size(); j++) {
                //i=1 ，insertColumns.size()+i开始
                tempindex = j + 1 + i * insertColumns.size();
                tempPlaceholderList.add("$" + tempindex);
            }
            List<? extends Serializable> list = Arrays.asList(loginEvent.getLoginTime(), loginEvent.getDeviceid(), loginEvent.getUserid(), loginEvent.getIpAddress(), loginEvent.getLoginType(), loginEvent.isSuccess(), loginEvent.getFailureReason());
            tuples.addAll(list);
            String format = String.join(", ", tempPlaceholderList);
            String format1 = String.format("(%s)", format);
            placeholderList.add(format1);
        }

        String placeholders = String.join(", ", placeholderList);

        String sql = String.format(
                "INSERT INTO wz_login_event (%s) VALUES %s ",
                columns,
                placeholders
        );

        return client.preparedQuery(sql.toString())
                .execute(Tuple.from(tuples))
                .onItem().transform(rows -> {
                    int rowCount = rows.rowCount();
                    LOG.infof("wz_Login_event", "批量登录日志成功", "count=" + rowCount);
                    return rowCount;
                })
                .onFailure().recoverWithUni(throwable -> {
                    LOG.errorf("wz_Login_event", "批量登录日志失败", throwable,
                            "count=" + loginEvents.size());
                    return Uni.createFrom().item(0);
                });
    }
}
